{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "替换后的文本： 甄一德个人网页的网址为http://abc138qaz，喜欢语文、数学和科学。\n",
      "提取的科目： ['数学', '科学']\n",
      "数字替换后的文本： 张三个人网页的网址为http://abc***qaz，喜欢语文、数学和科学。\n",
      "匹配的字符串： ['http://abc']\n"
     ]
    }
   ],
   "source": [
    "import re\n",
    "\n",
    "# 原始文本\n",
    "text = \"张三个人网页的网址为http://abc138qaz，喜欢语文、数学和科学。\"\n",
    "\n",
    "# (1) 用自己的名字替换张三\n",
    "your_name = \"甄一德\"\n",
    "result1 = re.sub(r'张三', your_name, text)\n",
    "print(\"替换后的文本：\", result1)\n",
    "\n",
    "# (2) 提取数学和科学\n",
    "result2 = re.findall(r'数学|科学', text)\n",
    "print(\"提取的科目：\", result2)\n",
    "\n",
    "# (3) 将所有数字替换为*\n",
    "result3 = re.sub(r'\\d', '*', text)\n",
    "print(\"数字替换后的文本：\", result3)\n",
    "\n",
    "# (4) 提取以h开头以c结尾的字符串\n",
    "result4 = re.findall(r'h.*?c', text)\n",
    "print(\"匹配的字符串：\", result4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "从sea.txt中提取的前5个关键词及权重:\n",
      "海洋: 0.5463\n",
      "108kW: 0.5364\n",
      "20: 0.1533\n",
      "盐差: 0.1533\n",
      "潮汐能: 0.1346\n"
     ]
    }
   ],
   "source": [
    "import jieba\n",
    "import jieba.analyse\n",
    "\n",
    "def get_keywords(text, topK=5, withWeight=True, allowPOS=()):\n",
    "\n",
    "    keywords = jieba.analyse.extract_tags(\n",
    "        sentence=text,\n",
    "        topK=topK,\n",
    "        withWeight=withWeight,\n",
    "        allowPOS=allowPOS\n",
    "    )\n",
    "    return keywords\n",
    "\n",
    "\n",
    "try:\n",
    "    with open('data/sea.txt', 'r', encoding='utf-8') as file:\n",
    "        text = file.read()\n",
    "except FileNotFoundError:\n",
    "    print()\n",
    "    exit()\n",
    "\n",
    "\n",
    "keywords = get_keywords(text)\n",
    "\n",
    "\n",
    "print(\"从sea.txt中提取的前5个关键词及权重:\")\n",
    "for word, weight in keywords:\n",
    "    print(f\"{word}: {weight:.4f}\")  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "ename": "AttributeError",
     "evalue": "'ImageDraw' object has no attribute 'textbbox'",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mAttributeError\u001b[0m                            Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-17-b551712e82cd>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m     11\u001b[0m \u001b[0mw\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mWordCloud\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mfont_path\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34mr'data/horse.png'\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     12\u001b[0m \u001b[0mw\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mWordCloud\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mfont_path\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34mr'data/FZFSJW.TTF'\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mbackground_color\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m'white'\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mmask\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mimage\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 13\u001b[1;33m \u001b[0mw\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mgenerate\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mtxt\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m     14\u001b[0m \u001b[0mw\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mto_file\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34mr'data/test.png'\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     15\u001b[0m \u001b[0mplt\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mimshow\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mw\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0minterpolation\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m'bilinear'\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32mC:\\Anaconda3\\lib\\site-packages\\wordcloud\\wordcloud.py\u001b[0m in \u001b[0;36mgenerate\u001b[1;34m(self, text)\u001b[0m\n\u001b[0;32m    640\u001b[0m         \u001b[0mself\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    641\u001b[0m         \"\"\"\n\u001b[1;32m--> 642\u001b[1;33m         \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mgenerate_from_text\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mtext\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m    643\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    644\u001b[0m     \u001b[1;32mdef\u001b[0m \u001b[0m_check_generated\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32mC:\\Anaconda3\\lib\\site-packages\\wordcloud\\wordcloud.py\u001b[0m in \u001b[0;36mgenerate_from_text\u001b[1;34m(self, text)\u001b[0m\n\u001b[0;32m    622\u001b[0m         \"\"\"\n\u001b[0;32m    623\u001b[0m         \u001b[0mwords\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mprocess_text\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mtext\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 624\u001b[1;33m         \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mgenerate_from_frequencies\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mwords\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m    625\u001b[0m         \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    626\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32mC:\\Anaconda3\\lib\\site-packages\\wordcloud\\wordcloud.py\u001b[0m in \u001b[0;36mgenerate_from_frequencies\u001b[1;34m(self, frequencies, max_font_size)\u001b[0m\n\u001b[0;32m    452\u001b[0m             \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    453\u001b[0m                 self.generate_from_frequencies(dict(frequencies[:2]),\n\u001b[1;32m--> 454\u001b[1;33m                                                max_font_size=self.height)\n\u001b[0m\u001b[0;32m    455\u001b[0m                 \u001b[1;31m# find font sizes\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    456\u001b[0m                 \u001b[0msizes\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;33m[\u001b[0m\u001b[0mx\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m]\u001b[0m \u001b[1;32mfor\u001b[0m \u001b[0mx\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mlayout_\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32mC:\\Anaconda3\\lib\\site-packages\\wordcloud\\wordcloud.py\u001b[0m in \u001b[0;36mgenerate_from_frequencies\u001b[1;34m(self, frequencies, max_font_size)\u001b[0m\n\u001b[0;32m    509\u001b[0m                     font, orientation=orientation)\n\u001b[0;32m    510\u001b[0m                 \u001b[1;31m# get size of resulting text\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 511\u001b[1;33m                 \u001b[0mbox_size\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mdraw\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mtextbbox\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m0\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mword\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mfont\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mtransposed_font\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0manchor\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m\"lt\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m    512\u001b[0m                 \u001b[1;31m# find possible places using integral image:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    513\u001b[0m                 result = occupancy.sample_position(box_size[3] + self.margin,\n",
      "\u001b[1;31mAttributeError\u001b[0m: 'ImageDraw' object has no attribute 'textbbox'"
     ]
    }
   ],
   "source": [
    "import jieba\n",
    "from wordcloud import WordCloud\n",
    "import matplotlib.pyplot as plt\n",
    "import imageio\n",
    "f = open(r'data/sea.txt',encoding='utf-8')\n",
    "t = f.read()\n",
    "f.close()\n",
    "words = jieba.lcut(t)\n",
    "txt=''.join(words)\n",
    "image=imageio.imread(r'data/horse.png')\n",
    "w = WordCloud(font_path=r'data/horse.png')\n",
    "w=WordCloud(font_path=r'data/FZFSJW.TTF',background_color='white',mask=image)\n",
    "w.generate(txt)\n",
    "w.to_file(r'data/test.png')\n",
    "plt.imshow(w, interpolation='bilinear')\n",
    "plt.axis(\"off\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import warnings\n",
    "\n",
    "warnings.filterwarnings(\"ignore\", message=\"`np.float` is a deprecated alias for the builtin `float`\")\n",
    "import jieba\n",
    "import numpy as np\n",
    "import os\n",
    "from gensim.models import Word2Vec\n",
    "from sklearn.metrics.pairwise import cosine_similarity\n",
    "\n",
    "\n",
    "try:\n",
    "    \n",
    "    script_dir = os.path.dirname(os.path.abspath(__file__))\n",
    "except NameError:\n",
    "    \n",
    "    script_dir = os.getcwd()\n",
    "\n",
    "\n",
    "train_data_path = os.path.join(script_dir,'data', 'TrainData.txt')\n",
    "zuoye1_path = os.path.join(script_dir, 'data', 'zuoye1.txt')\n",
    "zuoye2_path = os.path.join(script_dir, 'data', 'zuoye2.txt')\n",
    "\n",
    "\n",
    "def check_file(file_path, name):\n",
    "    if not os.path.exists(file_path):\n",
    "        print(f\"错误：未找到{name}文件 - {file_path}\")\n",
    "        print(f\"当前工作目录: {os.getcwd()}\")\n",
    "        print(f\"目录内容: {os.listdir(script_dir)}\")\n",
    "        return False\n",
    "    return True\n",
    "\n",
    "\n",
    "if not check_file(train_data_path, \"训练语料库\"):\n",
    "    exit()\n",
    "if not check_file(zuoye1_path, \"作业1\") or not check_file(zuoye2_path, \"作业2\"):\n",
    "    exit()\n",
    "\n",
    "\n",
    "with open(train_data_path, 'r', encoding='utf-8') as f:\n",
    "    \n",
    "    sentences = [line.strip().split() for line in f if line.strip()]\n",
    "\n",
    "\n",
    "try:\n",
    "    model = Word2Vec(\n",
    "        sentences,\n",
    "        vector_size=100,  \n",
    "        window=5,        \n",
    "        min_count=1,      \n",
    "        workers=4,        \n",
    "        epochs=5         \n",
    "    )\n",
    "except TypeError:\n",
    "    \n",
    "    model = Word2Vec(\n",
    "        sentences,\n",
    "        size=100,         \n",
    "        window=5,\n",
    "        min_count=1,\n",
    "        workers=4,\n",
    "        iter=5            \n",
    "    )\n",
    "print(\"Word2Vec模型训练完成\")\n",
    "\n",
    "# 读取两份作业\n",
    "with open(zuoye1_path, 'r', encoding='utf-8') as f:\n",
    "    zuoye1 = f.read()\n",
    "with open(zuoye2_path, 'r', encoding='utf-8') as f:\n",
    "    zuoye2 = f.read()\n",
    "\n",
    "# 分词函数\n",
    "def segment(text):\n",
    "   \n",
    "    return [word for word in jieba.lcut(text) if word.strip()]\n",
    "\n",
    "\n",
    "zuoye1_words = segment(zuoye1)\n",
    "zuoye2_words = segment(zuoye2)\n",
    "\n",
    "\n",
    "def text_to_vector(words, model, vector_size):\n",
    "    \"\"\"将文本转换为向量表示\"\"\"\n",
    "    vector = np.zeros(vector_size)\n",
    "    count = 0\n",
    "    for word in words:\n",
    "        if word in model.wv:\n",
    "            vector += model.wv[word]\n",
    "            count += 1\n",
    "    if count > 0:\n",
    "        return vector / count  \n",
    "    return vector\n",
    "\n",
    "\n",
    "try:\n",
    "    vector_size = model.vector_size\n",
    "except AttributeError:\n",
    "    vector_size = model.vector_size\n",
    "\n",
    "\n",
    "zuoye1_vector = text_to_vector(zuoye1_words, model, vector_size)\n",
    "zuoye2_vector = text_to_vector(zuoye2_words, model, vector_size)\n",
    "\n",
    "\n",
    "similarity = cosine_similarity([zuoye1_vector], [zuoye2_vector])[0][0]\n",
    "print(f\"两份作业的相似度: {similarity:.4f}\")\n",
    "\n",
    "\n",
    "with open('作业相似度结果.txt', 'w', encoding='utf-8') as f:\n",
    "    f.write(f\"基于Word2Vec模型的作业相似度分析\\n\")\n",
    "    f.write(f\"作业1: {zuoye1_path}\\n\")\n",
    "    f.write(f\"作业2: {zuoye2_path}\\n\")\n",
    "    f.write(f\"相似度值: {similarity:.4f}\\n\")\n",
    "    f.write(\"\\n相似度解释:\\n\")\n",
    "    f.write(\"0.9以上: 非常相似（可能存在抄袭）\\n\")\n",
    "    f.write(\"0.7-0.9: 比较相似\\n\")\n",
    "    f.write(\"0.5-0.7: 一般相似\\n\")\n",
    "    f.write(\"0.3-0.5: 较低相似\\n\")\n",
    "    f.write(\"0.3以下: 差异较大\\n\")\n",
    "\n",
    "print(\"分析结果已保存至: 作业相似度结果.txt\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Word2Vec模型训练完成\n",
      "两份作业的相似度: 0.9884\n",
      "分析结果已保存至: 作业相似度结果.txt\n"
     ]
    }
   ],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
